import type { ComponentPublicInstance } from 'vue'
import { useCssVar } from '@vueuse/core'

export default class ColorUtils {
  /**
   * 修改主要颜色和辅助色的颜色变量，例如：
   * --el-color-primary
   * --el-color-primary-light-3
   * --el-color-primary-light-5
   * --el-color-primary-light-7
   * --el-color-primary-light-8
   * --el-color-primary-light-9
   * --el-color-primary-dark-2
   * @param element 修改的元素
   * @param varName 变量名
   * @param colorValue 颜色值
   */
  public static setColor(
    element: globalThis.Ref<HTMLElement | ComponentPublicInstance | null>,
    varName: 'primary' | 'success' | 'warning' | 'danger' | 'error' | 'info',
    colorValue: string
  ) {
    useCssVar(`--el-color-${varName}`, element).value = colorValue
    for (let i = 3; i <= 9; i++) {
      if (i == 4 || i == 6) {
        continue
      }
      useCssVar(`--el-color-${varName}-light-${i}`, element).value = ColorUtils.getLightColor(
        colorValue,
        i / 10
      )
    }
    useCssVar(`--el-color-${varName}-dark-2`, element).value = ColorUtils.getDarkColor(
      colorValue,
      2 / 10
    )
  }

  /**
   *获取暗黑色
   * @param hex
   * @param level
   */
  public static getDarkColor(hex: string, level: number): string {
    const reg = /^#?[0-9A-Fa-f]{3}(?:[0-9A-Fa-f]{3})?$/
    if (!reg.test(hex)) {
      throw new Error('color格式不正确')
    }
    return this.rgbToHex(this.hexToRgb(hex).map((rgb) => Math.round(rgb * (1 - level))))
  }

  /**
   * 获取指定颜色的明亮色
   * @param hex
   * @param level
   */
  public static getLightColor(hex: string, level: number): string {
    const reg = /^#?[0-9A-Fa-f]{3}(?:[0-9A-Fa-f]{3})?$/
    if (!reg.test(hex)) {
      throw new Error('color格式不正确')
    }
    return this.rgbToHex(this.hexToRgb(hex).map((rgb) => Math.round((255 - rgb) * level + rgb)))
  }

  /**
   * 六位十六进制字符串拆分为三个元素的数组，每个元素都是十进制数字。
   * @param hex 颜色字符串
   */
  public static hexToRgb(hex: string): number[] {
    //去除最前面的#字符
    hex = hex.replace('#', '')
    if (hex.length === 6) {
      return Array.from({ length: hex.length / 2 }, (_, i) => hex.substring(i * 2, i * 2 + 2)).map(
        (value) => parseInt(value, 16)
      )
    } else {
      return Array.from({ length: hex.length }, (_, i) => hex.substring(i, i + 1)).map((value) =>
        parseInt(value + value, 16)
      )
    }
  }

  /**
   * rgb转十六进制字符串
   * @param rgbArray
   */
  public static rgbToHex(rgbArray: number[]): string {
    return (
      '#' +
      rgbArray
        .map((rgbArray) => {
          const str = rgbArray.toString(16)
          return str.length < 2 ? `0${str}` : str
        })
        .join('')
    )
  }
}
